<?php
/**
 * PrynLib
 * @copyright 2007-2009 Prynel
 * @author Olivier ROGER <roger.olivier@gmail.com>
 * @category libPrynel
 * @package Auth
 * @version $Revision: 80 $
 */

/**
 * Classe permettant la gestion des droits d'accès aux ressources.
 * @category libPrynel
 * @package Auth
 * @version 1.1.1 
 * @author Olivier ROGER <roger.olivier@gmail.com>
 * @copyright  2007-2009 Prynel
 *       
 * <code>
 * $ACL = new Auth_ACl($idLvl);
 * $ACL->addRessource("post",$ACL->guestLevel);
 * $ACL->addRessource(array("delete"=>1,"edit"=>2,"reply"=>3));
 * $ACL->addRessource(array('test1','test2','test3'),3);
 * $ACL->allowUser('delete');
 * $ACL->allowUser('read',false);
 * if($ACL->isAllowed('delete'))
 * 		echo 'Je supprime';
 * else
 * 		echo'Droits insuffisant';
 * $ACL->allowLevel('edit',3,false);
 * </code>
 */

class Auth_ACL
{
	
	/**
	 * Niveau de l'utilisateur invité
	 *
	 * @var int
	 * @access public
	 */
	public 	$guestLevel;
	
	/**
	 * Niveau de l'utilisateur admin
	 *
	 * @var int
	 * @access public
	 */
	public 	$adminLevel;
	
	/**
	 * Niveau de l'utilisateur suprême
	 *
	 * @var int
	 * @access public
	 */
	public 	$godLevel;
	
	/**
	 * Niveau de l'utilisateur courant
	 *
	 * @var int
	 * @access private
	 */
	private $userLevel;
	
	/**
	 * Array des ressources
	 *
	 * @var array
	 * @access private
	 */
	private $ressource;
	
	/**
	 * Array des exceptions d'utilisateur
	 *
	 * @var array
	 * @access public
	 */
	private $allowUser;
	
	/**
	 * Array des exceptions de niveau
	 *
	 * @var array
	 * @access public
	 */
	private $allowLevel;
	
	public function __construct($lvluser)
	{
		$this->userLevel	= $lvluser;
		$this->guestLevel	= 99;
		$this->adminLevel	= 2;
		$this->godLevel		= 1;
		$this->ressource	= array();
		$this->allowUser	= array();
		$this->allowLevel	= array();
	}
	
	/**
	 * Ajoute une ressource et son niveau d'accès.
	 * /!\ Une ressource ne doit pas être numérique
	 *
	 * @param mixed $nom Tableau ou nom de ressource
	 * @param int $maxlevel Niveau maximal pour avoir accès à cette ressource
	 * @return void
	 */
	public function addRessource($nom,$maxlevel=0)
	{
		if(is_array($nom))
		{
			foreach($nom as $key=>$valeur)
			{
				if(is_int($key))
					$this->ressource[$valeur] = $maxlevel;
				else
					$this->ressource[$key]	 = $valeur;
			}
		}
		else
		{
			$this->ressource[$nom]	= $maxlevel;
		}
	}
	
	/**
	 * Vérifie si l'utilisateur est autorisé à consulter la ressource
	 * 
	 * @param string $nom_ressource
	 * @param boolean $allowAdmin Admin toujours autorisé ?
	 * @return boolean
	 */
	public function isAllowed($nom_ressource,$allowAdmin= false)
	{
		if(isset($this->ressource[$nom_ressource]))
		{
			if($this->isGod())
				return true;
			
			if($allowAdmin && $this->isAdmin())
				return true;
			
			if(isset($this->allowUser[$nom_ressource]) && $this->allowUser[$nom_ressource])
				return true;
			elseif(isset($this->allowUser[$nom_ressource]) && $this->allowUser[$nom_ressource]===false)
				return false;
			
			if(isset($this->allowLevel[$nom_ressource]) && $this->allowLevel[$nom_ressource][0] == $this->userLevel && $this->allowLevel[$nom_ressource][1])
				return true;
			elseif(isset($this->allowLevel[$nom_ressource]) && $this->allowLevel[$nom_ressource][0] == $this->userLevel && $this->allowLevel[$nom_ressource][1]===false)
				return false;
			
			///!\ Dans mon cas les rang avec le plus de droit on le lvl le plus petit d'où le <=
			// A changer au besoin donc...
			if($this->userLevel <= $this->ressource[$nom_ressource] || $this->ressource[$nom_ressource]==$this->guestLevel)
				return true;
				
			return false;
		}
		else
			throw new Util_ExceptionHandler('La ressource n\'est pas définie');
		
	}
	
	/**
	 * Autorise ou non l'utilisateur sur une ressource spécifique
	 *
	 * @param string $nom_ressource
	 * @param boolean $allow
	 * @return void
	 */
	public function allowUser($nom_ressource,$allow=true)
	{
		if(isset($this->ressource[$nom_ressource]))
			$this->allowUser[$nom_ressource] = $allow;
		else
			throw new Util_ExceptionHandler('La ressource n\'est pas définie');
	}
	
	/**
	 * Autorise un lvl sur une ressource spécifique
	 *
	 * @param string $nom_ressource
	 * @param boolean $allow
	 * @return void
	 */
	public function allowLevel($nom_ressource,$lvl,$allow=true)
	{
		if(isset($this->ressource[$nom_ressource]))
			$this->allowLevel[$nom_ressource] = array($lvl,$allow);
		else
			throw new Util_ExceptionHandler('La ressource n\'est pas définie');
	}
	
	/**
	 * Vérifie si l'utilisateur est administrateur
	 * @access public
	 * @return void
	 */
	public function isAdmin()
	{
		if($this->userLevel == $this->adminLevel || $this->userLevel == $this->godLevel)
			return true;
		
		return false;
	}
	
	/**
	 * Vérifie si l'utilisateur est l'utilisateur suprême vibrant
	 * @access public
	 * @return boolean
	 */
	public function isGod()
	{
		if($this->userLevel == $this->godLevel)
			return true;
		
		return false;
	}
	
	/**
	 * Vérifie si l'utilisateur a les droits d invité
	 * @access public
	 * @return boolean
	 */
	public function isGuest()
	{
		if($this->userLevel == $this->guestLevel)
			return true;
		
		return false;
	}
	
	/**
	 * Retourne le niveau d'accès de l'utilisateur
	 * @since 1.1.0
	 * @return int
	 */
	public function getLevel()
	{
		return $this->userLevel;
	}
	/**
	 * Vide toutes les ressources et exceptions
	 * @return void
	 */
	public function reset()
	{
		$this->ressource 	= null;
		$this->allowLevel	= null;
		$this->allowUser	= null;
	}
	
	public function __sleep()
	{
		return array('userLevel','guestLevel','adminLevel','godLevel','ressource','allowUser','allowLevel');
	}
	
}
 ?>